<?php

namespace plugin\admin\app\controller;

use Exception;
use GuzzleHttp\Exception\GuzzleException;
use plugin\admin\app\common\service\jdApi;
use plugin\admin\app\common\service\thApi;
use plugin\admin\app\model\Order;
use plugin\admin\app\model\Shop;
use plugin\admin\app\model\TaskLog;
use support\Request;
use support\Response;
use Respect\Validation\Validator as v;
use think\facade\Cache;
use function Symfony\Component\Translation\t;

/**
 * 企业
 */
class UploadDataController extends Crud
{
    const USER_UP_SPU_LIST = 'userUpSpuList';
    const USER_UP_CONFIG = 'userUpConfig';

    /**
     * 浏览
     * @return Response
     */
    public function index(): Response
    {
        return view('upload-data/index');
    }

    public static function dataDb(): array
    {
        return [
            "data"             => [],
            "upNum"            => 0,
            "upStatus"         => false, // 是否上传完成
            "success"          => 0,
            "error"            => 0,
            "exist"            => 0,
            "count"            => 0,
            "shopId"           => "",
            "shopInfo"         => "",
            "shopCategoryId"   => "",
            "shopCategoryName" => "",
            "price_config"     => "",
            "anaSuccess"       => 0, // 解析数据成功
            "anaError"         => 0, // 解析数据失败
            "add_type"         => 0
        ];
    }
    /**
     * 店铺设置
     * @return Response
     */
    public function config(): Response
    {
        return view('upload-data/config');
    }

    /**
     * @throws Exception
     * 获取存储的spu连接
     */
    public function spuList(Request $request): Response
    {
        $data = Cache::get('upConfig');
        $spuDataList = Cache::get('spuList');
        $data['data'] = $spuDataList;
        $data['code'] = 0;
        return json($data);
    }

    /**
     * @throws Exception
     * 处理spu并存储
     */
    public function dataHandling(Request $request): Response
    {
        $verifyRes = v::input($request->post(), [
            'linkData' => v::NotEmpty()->setName('商品链接')
        ]);
        preg_match_all('/[0-9]+/', $verifyRes['linkData'], $matches);
        $task_id = self::generateUniqueRandomNumber();
        $linkData = [];
        foreach ($matches[0] as $key => $value) {
            $value = str_replace('_', '', $value);
            $value = str_replace('.html', '', $value);
            if($value != 1688) {
                $linkData[$key]['spu_id'] = $value;
                $linkData[$key]['upStatus'] = 0; // 0未传，1成功，2失败
                $linkData[$key]['goodsInfo'] = [];
                $linkData[$key]['msg'] = '';
                $linkData[$key]['anaStatus'] = 0;
            }
        }
        $data = self::dataDb();
        $data['data'] = [];
        $data['count'] = count($linkData);
        $data['task_id']  = $task_id;
        // 存储redis
        Cache::set('spuList', $linkData);
        Cache::set('upConfig', $data);
        return self::success('成功', $linkData);
    }

    /**
     * @param int $length
     * @return string
     * 生成任务id，并且判断是否存在
     */
    public static function generateUniqueRandomNumber(int $length = 8): string
    {
        // 定义数字字符集合
        $characters = '0123456789';
        $charactersLength = strlen($characters);
        $randomNumber = '';
        // 生成随机数
        for ($i = 0; $i < $length; $i++) {
            $randomNumber .= $characters[rand(0, $charactersLength - 1)];
        }
        // 检查是否重复
        $verifyCode = TaskLog::where('task_id', $randomNumber)->count();
        if ($verifyCode == 0) {
            // 若唯一，则返回
            return $randomNumber;
        } else {
            // 若重复，则重新生成
            return self::generateUniqueRandomNumber($length);
        }
    }

    /**
     * @throws Exception
     * 获取配置信息并存储
     */
    public function getConfig(Request $request): Response
    {
        $verifyRes = v::input($request->post(), [
            'shopId'           => v::NotEmpty()->setName('店铺id'),
            'shopCategoryId'   => v::NotEmpty()->setName('店内分类'),
            'shopCategoryName' => v::NotEmpty()->setName('店内分类'),
            'price_config'     => v::NotEmpty()->setName('价格增加'),
            'add_type'         => v::NotEmpty()->setName('上传类型'),
        ]);
        $shopInfo = Shop::where('id', $verifyRes['shopId'])->get();
        $verifyRes['shopInfo'] = $shopInfo[0];
        $upConfig = Cache::get('upConfig');
        $new_data = array_merge($upConfig, $verifyRes);
        Cache::set('upConfig', $new_data);
        return $this->success();
    }

    /**
     * @throws Exception
     * 清空数据
     */
    public function clearLinkData(Request $request): Response
    {
        Cache::delete('spuList');
        Cache::delete('upConfig');
        return $this->success();
    }

    /**
     * 执行上传
     * @throws GuzzleException
     * @throws Exception
     */
    public function upMake(Request $request): Response
    {
        // 0. 判断今日剩余，如果没有了直接结束
        $orderInfo = OrderController::getOrder(admin());
        if($orderInfo['today'] >= admin('num')) {
            return $this->success("今日数据已用尽", ['type' => 1]);
        }
        // 判断账号是否过期
        $stop_at = strtotime(admin('stop_at'));
        if(time() >= $stop_at) {
            return $this->success("账号已过期", ['type' => 1]);
        }
        $time = [];
        $verifyRes = v::input($request->post(), [
            'upNum' => v::Number()->setName('上传序号')
        ]);
        $time[1] = dateTime();
        $upConfig = Cache::get('upConfig');
        $upConfig['upNum'] = $upConfig['upNum']+1;
        Cache::set('upConfig', $upConfig);
        // 1. 获取数据
        $upSpuList = Cache::get('spuList');
        $upConfig = Cache::get('upConfig');
        $upConfig['data'] = $upSpuList;
        $redisData = $upConfig;
        $upNum = $verifyRes['upNum'];
        // 判断一下，如果还请求，没有数据了直接返回结束
        if($upNum >= $upConfig['count']) {
            return $this->success("ok", $redisData);
        }
        // 更新数据--start
        $spuInfo = $upSpuList[$upNum];
        // 2. 采集数据
        $goodsData = thApi::getData($spuInfo['spu_id'], admin());
//        Cache::set('goodsData', $goodsData);
//        p(111);
//        $goodsData = Cache::get('goodsData');
        $time[2] = dateTime();
        if($goodsData['status']) { // 解析成功
            $spuInfo['goodsInfo'] = $goodsData['data'];
            $spuInfo['anaStatus'] = 1;
            // * 更新缓存
            $orderInfo = OrderController::getOrder(admin());
            $orderInfo['today'] = $orderInfo['today'] + 1;
            Cache::set('orderInfo_'.admin('company_id'), $orderInfo);
            $upConfig = Cache::get('upConfig');
            $upConfig['anaSuccess'] = $upConfig['anaSuccess']+1;
            Cache::set('upConfig', $upConfig);
            // 开始上品
            $insertRes = jdApi::goodsInsert($goodsData['data'], $redisData, $upConfig['shopInfo'], $upConfig['add_type']);
            $time[3] = dateTime();
            $statusCode = $insertRes['statusCode'];
            if($insertRes['status']) {
                $spuInfo['upStatus'] = 1;
                $upConfig = Cache::get('upConfig');;
                $upConfig['success'] = $upConfig['success']+1;
                Cache::set('upConfig', $upConfig);
                $spuInfo['msg'] = '上品成功';
            } else {
                $spuInfo['upStatus'] = 2;
                $spuInfo['msg'] = $insertRes['msg'];
                $upConfig = Cache::get('upConfig');
                $upConfig['error'] = $upConfig['error']+1;
                Cache::set('upConfig', $upConfig);
            }
        } else { // 解析失败
            $statusCode = $goodsData['statusCode'];
            $spuInfo['anaStatus'] = 2;
            $upConfig = Cache::get('upConfig');
            $upConfig['anaError'] = $upConfig['anaError']+1;
            $upConfig['error'] = $upConfig['error']+1;
            Cache::set('upConfig', $upConfig);
            $spuInfo['upStatus']  = 0;
            $spuInfo['msg']       = $goodsData['msg'];
            $spuInfo['goodsInfo'] = $goodsData['data'];
            if($goodsData['msg'] == "无上品权限") {
                $upConfig['type'] = 1;
                return $this->success($goodsData['msg'], $upConfig);
            }
        }
        $time[4] = dateTime();
        $spuInfo['time'] = $time;
        $spuList = Cache::get('spuList');
        $spuList[$upNum] = $spuInfo;
        Cache::set('spuList', $spuList);
        self::inseTasksLog($spuInfo['spu_id'], $redisData['task_id'], $spuInfo, $spuInfo['anaStatus'], $goodsData['code'], $spuInfo['upStatus'], $statusCode, $spuInfo['msg']);
        $upSpuList = Cache::get('spuList');
        $upConfig = Cache::get('upConfig');
        $upConfig['data'] = $upSpuList;
        return $this->success("ok", $upConfig);
    }

    /**
     * 更新上传记录
     * @param $spu_id
     * @param $task_id
     * @param $goodsData
     * @param $ana_status
     * @param $ana_code
     * @param $up_status
     * @param $statusCode
     * @param $msg
     * @return false
     * @throws Exception
     */
    public static function inseTasksLog($spu_id, $task_id, $goodsData, $ana_status, $ana_code, $up_status, $statusCode, $msg): bool
    {
        $data = [
            'spu_id'         => $spu_id,
            'task_id'        => $task_id,
            'company_id'     => admin('company_id'),
            'data'           => json_encode($goodsData),
            'ana_status'     => $ana_status,
            'consume_status' => $ana_code, // 0 代表未消费，1 代表已消费
            'up_status'      => $up_status, // 0是未执行，1 是成功，2 是未执行
            'status_code'    => $statusCode, // 状态码
            'msg'            => $msg,
            'created_at'     => dateTime(),
            'time'           => '2.' . + rand(0, 9)
        ];
        TaskLog::insert($data);
        return true;
    }

    /**
     * 店内分类获取
     * @throws GuzzleException
     */
    public function shopCategoryList(Request $request): Response
    {
        $verifyRes = v::input($request->post(), [
            'id' => v::NotEmpty()->setName('店铺id')
        ]);
        // 缓存获取店铺信息
        $shopInfo = Shop::where(['id' => $verifyRes['id']])->first();
        $res = jdApi::queryCategoriesByOrgCode($shopInfo);
        return $this->success('成功', $res);
    }

}
